package com.henu.engineer.service

import com.alibaba.fastjson.JSONArray
import com.alibaba.fastjson.JSONObject
import com.henu.engineer.dao.mapper.student.*
import com.henu.engineer.dao.mapper.teachingoutline.CourseTeachXmlMapper
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service

/**
 * @author noexcept
 * @since 2021/8/11 17:00
 */
@Service
class AchieveDegreeService {

    @Autowired
    lateinit var studentGraduationAchievedXmlMapper: StudentGraduationAchievedXmlMapper

    @Autowired
    lateinit var studentCourseAchievedXmlMapper: StudentCourseAchievedXmlMapper

    @Autowired
    lateinit var courseGoalAchievedXmlMapper: CourseGoalAchievedXmlMapper

    @Autowired
    lateinit var loginService: LoginService

    @Autowired
    lateinit var studentXmlMapper: StudentXmlMapper

    @Autowired
    lateinit var courseTeachXmlMapper: CourseTeachXmlMapper

    @Autowired
    lateinit var achieveDegreeGenerateService: AchieveDegreeGenerateService

    /**
     * 学生毕业达成度
     */
    fun getStudentGraduationAchieved(studentId: String): Double {
        val achieved = studentGraduationAchievedXmlMapper.selectByStudentId(studentId)
        return if (achieved !== null) achieved.achieveScale else 0.0
    }

    /**
     * 某个学生所有课程的达成度
     */
    fun getStudentCourseAchieved(studentId: String): JSONObject {
        val res = JSONObject()
        res["studentId"] = loginService.currentStudent!!.id
        res["studentName"] = loginService.currentStudent!!.name
        val data = JSONArray()
        res["data"] = data
        studentCourseAchievedXmlMapper.selectListByStudentId(studentId).forEach {
            val item = JSONObject()
            item["courseId"] = it.courseId
            item["courseName"] = it.courseName
            item["achievedScale"] = it.achievedScale
            item["semester"] = it.semester
            data.add(item)
        }
        return res
    }

    /**
     * 查询某学生某课程的所有目标达成度
     */
    fun getCourseGoalAchieved(studentId: String, courseId: String): JSONObject {
        val res = JSONObject()
        val data = JSONArray()
        res["data"] = data
        res["studentId"] = studentId
        res["studentName"] = ""
        res["courseId"] = courseId
        val courseTeach = courseTeachXmlMapper.selectCourseTeachByCourseId(courseId)
        res["courseName"] = ""
        res["msg"] = "SUCCESS"
        val student = studentXmlMapper.selectStudent(studentId)
        if (student == null || courseTeach == null) {
            res["msg"] = "bad studentId or courseId"
            return res
        }
        res["studentName"] = student.name
        res["courseName"] = courseTeach.name

        val list = courseGoalAchievedXmlMapper.selectByStudentIdCourseId(studentId, courseId)
        if (list.isEmpty()) {
            if (!achieveDegreeGenerateService.generateCourseGoalAchievedScale(studentId, courseId).first) {
                res["msg"] = "Data hasn't been generated yet!"
                return res
            }
        }
        list.forEach {
            val courseGoal = JSONObject()
            courseGoal["courseGoalId"] = it.courseGoalId
            courseGoal["achievedScale"] = it.achievedScale
            courseGoal["semester"] = it.semester
            data.add(courseGoal)
        }
        return res
    }

    /**
     * 某课程所有学生所有目标的达成度
     */
    fun getCourseGoalAchieved(courseId: String): JSONObject {
        val res = JSONObject()
        res["courseId"] = courseId
        val selectByCourseId = courseGoalAchievedXmlMapper.selectByCourseId(courseId)
        if (selectByCourseId.isEmpty()) {
            res["count"] = 0
            res["data"] = JSONArray()
            return res
        }

        val groupByStudentId = selectByCourseId.groupBy { it.studentId }
        res["count"] = groupByStudentId.size
        val data = JSONArray()

        groupByStudentId.forEach {
            val goalsPerStudent = JSONArray()
            val perStudent = JSONObject()
            perStudent["studentName"] = it.value.first().studentName
            perStudent["studentId"] = it.value.first().studentId
            perStudent["goals"] = goalsPerStudent
            it.value.forEach {
                val goalPerStudent = JSONObject()
                goalPerStudent["courseGoalId"] = it.courseGoalId
                goalPerStudent["courseGoalId"] = it.achievedScale
                goalsPerStudent.add(goalPerStudent)
            }
            perStudent["count"] = goalsPerStudent.size
            data.add(perStudent)
        }
        res["data"] = data
        res["count"] = data.size
        return res
    }

    /**
     * 某课程所有学生课程总目标达成度
     */
    fun getCourseGoalSumAchieved(courseId: String): JSONObject {
        val selectListByCourseId = studentCourseAchievedXmlMapper.selectListByCourseId(courseId)
        val res = JSONObject()
        res["courseId"] = courseId
        if (selectListByCourseId.isEmpty()) {
            res["count"] = 0
            res["data"] = JSONArray()
            return res
        }

        val groupByStudentId = selectListByCourseId.groupBy { it.studentId }
        val studentsArray = JSONArray()
        groupByStudentId.forEach {
            val perStudent = JSONObject()
            perStudent["studentId"] = it.value.first().studentId
            perStudent["studentName"] = it.value.first().studentName
            perStudent["achieveScale"] = it.value.first().achievedScale
            perStudent["semester"] = it.value.first().semester
            studentsArray.add(perStudent)
        }
        res["data"] = studentsArray
        res["count"] = studentsArray.size
        return res
    }

    /**
     * 返回某课程所有学生的课程达成度
     */
    fun getCourseAchieved(courseId: String): JSONObject {
        val selectByCourseId = courseGoalAchievedXmlMapper.selectByCourseId(courseId)
        val res = JSONObject()
        res["courseId"] = courseId
        if (selectByCourseId.isEmpty()) {
            res["count"] = 0
            return res
        }
        val groupByStudentId = selectByCourseId.groupBy { it.studentId }

        val studentsArray = JSONArray()
        groupByStudentId.forEach { student ->
            val perStudent = JSONObject()
            perStudent["courseAchieved"] = student.value.sumOf { it.achievedScale } / student.value.size
            perStudent["studentId"] = student.value.first().studentId
            perStudent["studentName"] = student.value.first().studentName
            perStudent["semester"] = student.value.first().semester
            studentsArray.add(perStudent)
        }
        res["data"] = studentsArray
        res["count"] = studentsArray.size
        return res
    }
}
